﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wicresoft.SMS.Data
{
    public class StateChecker : IStateCheck
    {
        private IConnectStringProvider _connParamProvider;
        private LogService log;
        private string product = "StateChackerTask.Data";

        public StateChecker(IConnectStringProvider configProvider)
        {
            _connParamProvider = configProvider;
            log = new LogService(configProvider.ConnectionString);
        }

        public List<Email> CheckStates(int timespan)
        {
            try
            {
                using (var dbacc = new Entities(_connParamProvider.ConnectionString))
                {                
                    TimeSpan times = new TimeSpan(0, timespan > 60 ? 60 : timespan, 0);
                    DateTime dt = DateTime.Now;
                    List<Email> list = new List<Email>();
                    var msgs = dbacc.Message.Where(m => m.State < 32);
                    if (msgs != null)
                    {
                        foreach (var item in msgs)
                        {
                            if ((dt - item.CreateTime) > times)
                            {
                                log.WriteLog(DateTime.Now, product, "Debug", item.ID.ToString() + " 原状态为 " + item.State + " 现标记为32 " + DateTime.Now.ToString(), "HOST");
                                item.State = 32;
                                Email email = BuildEmail(item);
                                if (email != null)
                                    list.Add(email);
                            }
                        }
                        dbacc.SaveChanges();
                    }
                    return list;
                }
            }
            catch (Exception ex)
            {
                log.WriteLog(DateTime.Now, product, "Exception", "Wicresoft.SMS.Data.StateChecker.CheckStates " + ex.ToString(), "HOST");
                return new List<Email>();
            }
        }

        private Email BuildEmail(Message msg)
        {
            if (msg == null)
                return null;
            using (var dbacc=new Entities(_connParamProvider.ConnectionString))
            {
                var user = dbacc.User.FirstOrDefault(u => u.UserID == msg.UserID);
                if (user != null)
                {
                    Email email = new Email();
                    email.To = user.Email;
                    email.Subject = "短信或许发送失败";
                    email.Content = string.Format("您于{2}发送给\"{0}\"的短信\"{1}\"由于长时间检查不到发送状态, 可能已经发送失败", msg.To, msg.Content, msg.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"));
                    return email;
                }
                else
                { return null; }
            }
        }


        public List<Email> CheckStates(int timespan, int pendingnum, string adminsemail, string url)
        {
            try
            {
                using (var dbacc = new Entities(_connParamProvider.ConnectionString))
                {
                    TimeSpan times = new TimeSpan(0, timespan > 60 ? 60 : timespan, 0);
                    DateTime dt = DateTime.Now;
                    List<Email> list = new List<Email>();
                    var all = dbacc.Message.Where(m => m.State < 32).GroupBy(m => m.BatchID);
                    if (all != null)
                    {
                        foreach (var batch in all)
                        {
                            var b = batch.Where(m => (dt - m.CreateTime) > times);
                            if (b != null && b.Count() > 0)
                            {
                                int batchid = b.First().BatchID;
                                int count = GetBatchCountByBatchID(batchid);

                                if (b.Count() == count && count >= pendingnum)
                                {
                                    Email email = BuildEmail(b.ToList(), "短信网关工作异常", adminsemail,url);
                                    if (email != null)
                                        list.Add(email);
                                }

                                foreach (var item in b)
                                {
                                    log.WriteLog(DateTime.Now, product, "Debug", item.ID.ToString() + " State原状态为 " + item.State + " 现标记为32 " + DateTime.Now.ToString(), "HOST");
                                    item.State = 32;                                    
                                }

                                Email emails = BuildEmail(b.ToList(), "您的短信可能已经发送失败", null,url);
                                if (emails != null)
                                    list.Add(emails);
                            }
                        }
                        dbacc.SaveChanges();
                    }
                   
                    return list;
                }
            }
            catch (Exception ex)
            {
                log.WriteLog(DateTime.Now, product, "Exception", "Wicresoft.SMS.Data.StateChecker.CheckStates(int timespan, int pendingnum) " + ex.ToString(), "HOST");
               // Wicresoft.SMS.Common.Logger.Error("CheckStates " + ex.ToString());
                if (ex.Message.Trim() != "The underlying provider failed on Open.")
                    return new List<Email>();
                else
                {
                   // Wicresoft.SMS.Common.Logger.Error("return null");
                    return null;
                }
            }
        }

        private Email BuildEmail(List<Message> msgs, string subject, string mailto, string url)
        {
            if (msgs == null)
                return null;
            using (var dbacc = new Entities(_connParamProvider.ConnectionString))
            {
                int userid = msgs.First().UserID;
                var user = dbacc.User.FirstOrDefault(u => u.UserID ==userid );
                if (user != null)
                {
                    string to = "";
                    foreach (var item in msgs)
                    {
                        to += item.To + "; ";
                    }

                    string who = mailto == null ? user.NameEN : "管理员";
                    string who_ = mailto == null ? "您" : "用户" + user.NameEN;
                    string _url = url;
                    _url += mailto == null ? "history/failed?batchid=" : "history/failed/company?batchid=";
                    _url += msgs.First().BatchID;

                    Email email = new Email();
                    email.To = mailto == null ? user.Email : mailto;
                    email.Subject = subject;

                    string body = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" +
                              "<html xmlns=\"http://www.w3.org/1999/xhtml\">" +
                              "<head>" +
                              "<title>FailedNotification.htm</title>" +
                              "<style type=\"text/css\">" +
                              ".style2leftcallcolor: #666666;font-size: medium;rightcall" +
                              ".style3leftcallfont-size: small;color: #333333;rightcall" +
                              "pleftcallmargin:6px;font-size:14px;rightcall" +
                              ".style4leftcallfont-family: \"Khmer UI\";font-size: 40px;rightcall" +
                              "</style>" +
                              "</head>" +
                              "<body style=\"text-align: left\">" +
                              "<p>亲爱的{0}:</p>" +
                              "<p>&nbsp;</p>" +
                              "<p> {1}于{2}发送给以下联系人的短信由于长时间检查不到发送状态, 可能已经发送失败</p>" +
                              "<p>{3}</p>" +
                              "<p>短信内容为：</p>" +
                              "<p style=\"margin-left: 40px\" class=\"style3\"><span class=\"style4\">&quot;</span>{4}<span class=\"style4\">&quot;</span></p>" +
                              "<p> 请点击<a href=\"{5}\">历史记录</a>查看发送失败短信的详细信息。</p>" +
                              "<p>&nbsp;</p>" +
                              "<p>如果您的电子邮件程序不支持点击“历史记录”，请将此链接粘贴至您的网络浏览器中</p>" +
                              "<p>{5}</p>" +
                              "<p>此邮件为系统自动发送，请勿回复，谢谢合作。</p>" +
                              "<p>&nbsp;</p>" +
                              "<p class=\"style2\">上海贝尔短信平台系统</p>" +
                              "<p class=\"style2\">{6}</p>" +
                              "</body>" +
                              "</html>";

                    email.Content = string.Format(body, who, who_, msgs.First().CreateTime, to, msgs.First().Content, _url, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                   // email.Content = string.Format("{3}于{2}发送给\"{0}\"的短信\"{1}\"由于长时间检查不到发送状态, 可能已经发送失败", to, msgs.First().Content, msgs.First().CreateTime.ToString("yyyy-MM-dd HH:mm:ss"), who);
                    return email;
                }
                else
                { return null; }
            }
        }

        private int GetBatchCountByBatchID(int batchid)
        {
            try
            {
                using (var dbacc = new Entities(_connParamProvider.ConnectionString))
                {
                    var batchall = dbacc.Message.Where(m => m.BatchID == batchid);
                    return batchall.Count();                    
                }
            }
            catch (Exception ex)
            {
                log.WriteLog(DateTime.Now, product, "Exception", "Wicresoft.SMS.Data.StateChecker.CheckStates(int timespan, int pendingnum) " + ex.ToString(), "HOST");
                return -1;
            }
        }
    }
}
